using System;
using Volo.Abp.DependencyInjection;

namespace MatrixFramework.Shared.Application.Caching
{
    /// <summary>
    /// 缓存键管理器
    /// </summary>
    public class CacheKeyManager : ITransientDependency
    {
        /// <summary>
        /// 获取租户缓存键
        /// </summary>
        public string GetTenantKey(Guid tenantId)
        {
            return $"tenant:{tenantId:N}";
        }

        /// <summary>
        /// 获取租户列表缓存键
        /// </summary>
        public string GetTenantListKey(string filter, int pageIndex, int pageSize)
        {
            return $"tenants:list:{filter?.ToLowerInvariant() ?? "all"}:{pageIndex}:{pageSize}";
        }

        /// <summary>
        /// 获取用户缓存键
        /// </summary>
        public string GetUserKey(Guid userId)
        {
            return $"user:{userId:N}";
        }

        /// <summary>
        /// 获取用户列表缓存键
        /// </summary>
        public string GetUserListKey(string filter, int pageIndex, int pageSize)
        {
            return $"users:list:{filter?.ToLowerInvariant() ?? "all"}:{pageIndex}:{pageSize}";
        }

        /// <summary>
        /// 获取用户权限缓存键
        /// </summary>
        public string GetUserPermissionsKey(Guid userId)
        {
            return $"user:{userId:N}:permissions";
        }

        /// <summary>
        /// 获取角色缓存键
        /// </summary>
        public string GetRoleKey(Guid roleId)
        {
            return $"role:{roleId:N}";
        }

        /// <summary>
        /// 获取角色权限缓存键
        /// </summary>
        public string GetRolePermissionsKey(Guid roleId)
        {
            return $"role:{roleId:N}:permissions";
        }

        /// <summary>
        /// 获取配置缓存键
        /// </summary>
        public string GetConfigKey(string configType, string configKey)
        {
            return $"config:{configType?.ToLowerInvariant()}:{configKey?.ToLowerInvariant()}";
        }

        /// <summary>
        /// 获取Keycloak令牌缓存键
        /// </summary>
        public string GetKeycloakTokenKey(string realm, string clientId)
        {
            return $"keycloak:token:{realm?.ToLowerInvariant()}:{clientId?.ToLowerInvariant()}";
        }

        /// <summary>
        /// 获取Keycloak用户缓存键
        /// </summary>
        public string GetKeycloakUserKey(string realm, string username)
        {
            return $"keycloak:user:{realm?.ToLowerInvariant()}:{username?.ToLowerInvariant()}";
        }

        /// <summary>
        /// 获取API速率限制缓存键
        /// </summary>
        public string GetRateLimitKey(string clientId, string endpoint, TimeSpan period)
        {
            var periodKey = period switch
            {
                var p when p.TotalSeconds <= 60 => "minute",
                var p when p.TotalHours <= 1 => "hour",
                var p when p.TotalDays <= 1 => "day",
                _ => "custom"
            };
            return $"ratelimit:{clientId?.ToLowerInvariant()}:{endpoint?.ToLowerInvariant()}:{periodKey}";
        }

        /// <summary>
        /// 获取健康检查缓存键
        /// </summary>
        public string GetHealthCheckKey(string serviceName)
        {
            return $"health:{serviceName?.ToLowerInvariant()}";
        }

        /// <summary>
        /// 获取统计数据缓存键
        /// </summary>
        public string GetStatisticsKey(string statisticType, DateTime date)
        {
            return $"stats:{statisticType?.ToLowerInvariant()}:{date:yyyy-MM-dd}";
        }

        /// <summary>
        /// 获取搜索结果缓存键
        /// </summary>
        public string GetSearchResultKey(string searchType, string searchQuery, int pageIndex, int pageSize)
        {
            // 使用查询的哈希值作为键的一部分，避免键过长
            var queryHash = System.Security.Cryptography.MD5.HashData(System.Text.Encoding.UTF8.GetBytes(searchQuery ?? ""));
            var queryHashString = Convert.ToHexString(queryHash)[..8].ToLowerInvariant();

            return $"search:{searchType?.ToLowerInvariant()}:{queryHashString}:{pageIndex}:{pageSize}";
        }

        /// <summary>
        /// 获取文件元数据缓存键
        /// </summary>
        public string GetFileMetadataKey(string fileHash)
        {
            return $"file:metadata:{fileHash?.ToLowerInvariant()}";
        }

        /// <summary>
        /// 获取会话缓存键
        /// </summary>
        public string GetSessionKey(string sessionId)
        {
            return $"session:{sessionId}";
        }

        /// <summary>
        /// 获取验证码缓存键
        /// </summary>
        public string GetVerificationCodeKey(string identifier, string type)
        {
            return $"verification:{type?.ToLowerInvariant()}:{identifier?.ToLowerInvariant()}";
        }

        /// <summary>
        /// 获取临时数据缓存键
        /// </summary>
        public string GetTempDataKey(string dataKey, Guid? userId = null)
        {
            var userPart = userId.HasValue ? $":{userId:N}" : "";
            return $"temp:{dataKey?.ToLowerInvariant()}{userPart}";
        }

        /// <summary>
        /// 获取通知缓存键
        /// </summary>
        public string GetNotificationKey(Guid userId, DateTime date)
        {
            return $"notifications:{userId:N}:{date:yyyy-MM-dd}";
        }

        /// <summary>
        /// 获取审计日志缓存键
        /// </summary>
        public string GetAuditLogKey(Guid? userId, string action, DateTime date)
        {
            var userPart = userId.HasValue ? $"{userId:N}:" : "";
            return $"audit:{userPart}{action?.ToLowerInvariant()}:{date:yyyy-MM-dd}";
        }

        /// <summary>
        /// 获取前缀模式，用于批量删除
        /// </summary>
        public string GetPrefixPattern(string prefix)
        {
            return $"{prefix.ToLowerInvariant()}:*";
        }

        /// <summary>
        /// 生成唯一的缓存键
        /// </summary>
        public string GenerateUniqueKey(string prefix, params object[] parameters)
        {
            var key = prefix.ToLowerInvariant();

            if (parameters != null && parameters.Length > 0)
            {
                var paramParts = new string[parameters.Length];
                for (int i = 0; i < parameters.Length; i++)
                {
                    paramParts[i] = parameters[i]?.ToString()?.ToLowerInvariant() ?? "null";
                }
                key += ":" + string.Join(":", paramParts);
            }

            return key;
        }
    }
}